package Thread;

/**
 * 赖汉模式创建单例模式多线程
 */

/**
 * 这是懒汉模式创建的单例模式的单线程
 */

class SingleThreadSingleton1{
   public static Object locker = new Object();
    private  static volatile SingleThreadSingleton1 instance = null;
    public static  SingleThreadSingleton1 getInstance(){
        if (instance==null){
            synchronized (locker){
                if (instance==null){
                    instance = new SingleThreadSingleton1();
                }
            }
        }
        return instance;
    }
    public SingleThreadSingleton1(){
        System.out.println("懒汉模式的单例模式的多线程模式被创建");
    }
    public  void  ShowMessage(){
        System.out.println("我的小野猫应该在一边应付生活，一边在等待我的信息");
        System.out.println("多线程懒汉式单例模式2 - 双重检查锁定实现");
    }
}
class SingleThreadSingleton{
    private  static SingleThreadSingleton instance = null;
    public  static  SingleThreadSingleton getInstance(){
        if (instance==null){
            instance = new SingleThreadSingleton();
        }
        return instance;
    }
    public SingleThreadSingleton(){
        System.out.println("懒汉模式的单例模式的单线程模式被创建");
    }
    public  void  ShowMessage(){
        System.out.println("我的小野猫应该在一边应付生活，一边在等待我的信息");
    }
}

/**
 * 这是使用懒汉模式创建的多线程的单例模式
 */
class SingletonLazy{
    private static  volatile SingletonLazy instance = null;
    private static  Object locker = new Object();


    //外层的if就是判定下看当前是否已经把instance实例创建出来
    // 同时为了避免“内存可见性”导致的读取的instance出现偏差，于是补上volatile。
    public  static  SingletonLazy getInstance(){
        if (instance == null){ //判定是否需要加锁，
            synchronized (locker){
                if (instance==null){  //判定是否 new对象
                    instance = new SingletonLazy();
                }

            }
        }
        return instance;
    }
    private SingletonLazy(){

    }
}
public class Demo26 {
    public static void main(String[] args) {
      SingleThreadSingleton1 s1 = SingleThreadSingleton1.getInstance();
      SingleThreadSingleton1 s2 = SingleThreadSingleton1.getInstance();
        System.out.println(s1==s2);
        s1.ShowMessage();

    }
    public static void main2(String[] args) {
        SingleThreadSingleton s1 = SingleThreadSingleton.getInstance();
        SingleThreadSingleton s2 = SingleThreadSingleton.getInstance();
        System.out.println(s1==s2);
        s1.ShowMessage();
    }
    public static void main1(String[] args) {
        SingletonLazy s1 = SingletonLazy.getInstance();
        SingletonLazy s2 = SingletonLazy.getInstance();
        System.out.println(s1==s2);
    }
}
